package com.github.zengfr.project.stepchain.processor;

import java.util.Map;

import org.springframework.stereotype.Component;

import com.github.zengfr.project.stepchain.IConditionLoopProcessor;
import com.github.zengfr.project.stepchain.IConditionSelector;
import com.github.zengfr.project.stepchain.IConditionSelectorProcessor;
import com.github.zengfr.project.stepchain.IConditionValidator;
import com.github.zengfr.project.stepchain.IProcessor;
import com.github.zengfr.project.stepchain.IProcessorBuilder;
/**
 * @author zengfr QQ:362505707/1163551688 Email:zengfr3000@qq.com
 *         https://github.com/zengfr/stepchain-spring-boot-starter
 */
@Component
public class ProcessorBuilder implements IProcessorBuilder {

	@Override
	public <A, B, C> IProcessor<A, C> createProcessor(IProcessor<A, B> first, IProcessor<B, C> second) {

		return new CompositeProcessor<>(first, second);
	}

	@Override
	public <I, O> IConditionLoopProcessor<I, O> createProcessor(IConditionValidator<I> validator, IProcessor<I, O> processor) {
		IConditionLoopProcessor<I, O> loopProcessor = new ConditionLoopProcessor<>();
		loopProcessor.setValidator(validator);
		loopProcessor.setProcessor(processor);
		return loopProcessor;
	}

	@Override
	public <I, O> IConditionSelectorProcessor<I, Boolean, O> createProcessor(IConditionValidator<I> validator, IProcessor<I, O> first, IProcessor<I, O> second) {

		IConditionSelectorProcessor<I, Boolean, O> selectorProcessor = new ConditionSelectorProcessor<>();
		selectorProcessor.setSelector(validator);
		selectorProcessor.setBranch(true, first);
		selectorProcessor.setBranch(false, second);
		return selectorProcessor;
	}

	@Override
	public <I, S, O> IConditionSelectorProcessor<I, S, O> createProcessor(IConditionSelector<I, S> selector) {

		return new ConditionSelectorProcessor<>();
	}

	@Override
	public <I, S, O> IConditionSelectorProcessor<I, S, O> createProcessor(IConditionSelector<I, S> selector, Map<S, IProcessor<I, O>> branchs) {

		IConditionSelectorProcessor<I, S, O> selectorProcessor = new ConditionSelectorProcessor<>();
		selectorProcessor.setSelector(selector);

		for (Map.Entry<S, IProcessor<I, O>> branch : branchs.entrySet()) {
			selectorProcessor.setBranch(branch.getKey(), branch.getValue());
		}
		return selectorProcessor;
	}

}
